package com.codeoss.framework.workflow.parser;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.codeoss.framework.expression.Expression;
import com.codeoss.framework.expression.ExpressionUtil;
import com.codeoss.framework.util.StringUtils;
import com.codeoss.framework.workflow.def.LineDef;
import com.codeoss.framework.workflow.def.NodeDef;
import com.codeoss.framework.workflow.def.WorkflowDef;
import com.codeoss.framework.workflow.def.WorkflowElementDef;
import com.codeoss.module.ir.model.IrWorkflow;
import com.codeoss.module.ir.service.IIrWorkflowService;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;

@Service
public class WorkflowParser implements IWorkflowElementParser,ApplicationContextAware {
    private ApplicationContext applicationContext;
    @Autowired
    private IIrWorkflowService irWorkflowService;
	@Override
	public WorkflowElementDef parse(IWorkflowElementParseContext workflowElementParseContext, ObjectNode objectNode) {
		// TODO Auto-generated method stub
		WorkflowDef workflowDef=new WorkflowDef();
		String code=objectNode.get("code").asText();
		workflowDef.setCode(code);
		
		JsonNode jsonNode=objectNode.get("documentExpression");
		if(jsonNode!=null) {
			Expression expression=ExpressionUtil.convertToExpression(jsonNode.asText(), Expression.EXPRESSION_TYPE_JAVASCRIPT);
			workflowDef.setDocumentExpression(expression);
		}
		
		jsonNode=objectNode.get("formCode");
		if(jsonNode!=null) {
			workflowDef.setFormCode(jsonNode.asText());
		}
		
		jsonNode=objectNode.get("mobileFormCode");
		if(jsonNode!=null) {
			workflowDef.setMobileFormCode(jsonNode.asText());
		}
		
		QueryWrapper<IrWorkflow> irWorkflowQuery=new QueryWrapper<IrWorkflow>();
		irWorkflowQuery.eq("code", code);
		IrWorkflow irWorkflow=irWorkflowService.getOne(irWorkflowQuery);
		workflowDef.setName(irWorkflow.getName());
		
		jsonNode=objectNode.get("startEventExpression");
		if(jsonNode!=null) {
			String startEventExpression=jsonNode.asText();
			if(!StringUtils.isEmpty(startEventExpression) && !"null".equals(startEventExpression)) {
				Expression expression=ExpressionUtil.convertToExpression(startEventExpression, Expression.EXPRESSION_TYPE_JAVASCRIPT);
				workflowDef.setStartEventExpression(expression);
			}
		}
		
		jsonNode=objectNode.get("endEventExpression");
		if(jsonNode!=null) {
			String endEventExpression=jsonNode.asText();
			if(!StringUtils.isEmpty(endEventExpression) && !"null".equals(endEventExpression)) {
				Expression expression=ExpressionUtil.convertToExpression(endEventExpression, Expression.EXPRESSION_TYPE_JAVASCRIPT);
				workflowDef.setEndEventExpression(expression);
			}
		}
		ArrayNode nodeArray=(ArrayNode)objectNode.get("nodeList");
		for(int i=0;i<nodeArray.size();i++) {
			ObjectNode childObjectNode=(ObjectNode)nodeArray.get(i);
			String type=childObjectNode.get("type").asText();
			IWorkflowElementParser parser=(IWorkflowElementParser)applicationContext.getBean(type+"NodeParser");
			NodeDef nodeDef=(NodeDef)parser.parse(workflowElementParseContext, childObjectNode);
			nodeDef.setWorkflowDef(workflowDef);
			workflowDef.addNode(nodeDef);
		}
		
		nodeArray=(ArrayNode)objectNode.get("lineList");
		for(int i=0;i<nodeArray.size();i++) {
			ObjectNode childObjectNode=(ObjectNode)nodeArray.get(i);
			IWorkflowElementParser parser=(IWorkflowElementParser)applicationContext.getBean("lineParser");
			LineDef lineDef=(LineDef)parser.parse(workflowElementParseContext, childObjectNode);
			
			NodeDef fromNodeDef=workflowDef.getNodeDefById(lineDef.getFromNodeId());
			lineDef.setFromNode(fromNodeDef);
			
			NodeDef toNodeDef=workflowDef.getNodeDefById(lineDef.getToNodeId());
			lineDef.setToNode(toNodeDef);
			
			workflowDef.addLine(lineDef);
		}
		return workflowDef;
	}

	@Override
	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
		// TODO Auto-generated method stub
		this.applicationContext=applicationContext;
	}
}
